<!doctype html><html lang=zh-cn dir=ltr>
<head><meta charset=utf-8>
<meta name=viewport content="width=device-width,initial-scale=1"><meta name=description content="DVWA File upload 过关秘籍.
LOW if( isset( $_POST[ &amp;#39;Upload&amp;#39; ] ) ) {  // Where are we going to be writing to?  $target_path = DVWA_WEB_PAGE_TO_ROOT . &amp;#34;hackable/uploads/&amp;#34;;  $target_path .= basename( $_FILES[ &amp;#39;uploaded&amp;#39; ][ &amp;#39;name&amp;#39; ] );   // Can we move the file to the upload folder?  // 完全没做过滤.  // 上传一个PHP文件也是可以的.  if( !move_uploaded_file( $_FILES[ &amp;#39;uploaded&amp;#39; ][ &amp;#39;tmp_name&amp;#39; ], $target_path ) ) {  // No  echo &amp;#39;&amp;lt;pre&amp;gt;Your image was not uploaded."><title>File Upload</title><link rel=canonical href=https://sdttttt.github.io/blog/file_upload/>
<link rel=stylesheet href=/scss/style.min.b80bf249ce4a22cf55e8d7340a0b37a2f2c10f54f3a9a49cb94b694a2eb0bbea.css><meta property="og:title" content="File Upload">
<meta property="og:description" content="DVWA File upload 过关秘籍.
LOW if( isset( $_POST[ &amp;#39;Upload&amp;#39; ] ) ) {  // Where are we going to be writing to?  $target_path = DVWA_WEB_PAGE_TO_ROOT . &amp;#34;hackable/uploads/&amp;#34;;  $target_path .= basename( $_FILES[ &amp;#39;uploaded&amp;#39; ][ &amp;#39;name&amp;#39; ] );   // Can we move the file to the upload folder?  // 完全没做过滤.  // 上传一个PHP文件也是可以的.  if( !move_uploaded_file( $_FILES[ &amp;#39;uploaded&amp;#39; ][ &amp;#39;tmp_name&amp;#39; ], $target_path ) ) {  // No  echo &amp;#39;&amp;lt;pre&amp;gt;Your image was not uploaded.">
<meta property="og:url" content="https://sdttttt.github.io/blog/file_upload/">
<meta property="og:site_name" content="SDTTTTT">
<meta property="og:type" content="article"><meta property="article:section" content="Blog"><meta property="article:tag" content="penetration test"><meta property="article:published_time" content="2020-04-12T10:46:06+08:00"><meta property="article:modified_time" content="2020-09-24T18:06:32+08:00">
<meta name=twitter:title content="File Upload">
<meta name=twitter:description content="DVWA File upload 过关秘籍.
LOW if( isset( $_POST[ &amp;#39;Upload&amp;#39; ] ) ) {  // Where are we going to be writing to?  $target_path = DVWA_WEB_PAGE_TO_ROOT . &amp;#34;hackable/uploads/&amp;#34;;  $target_path .= basename( $_FILES[ &amp;#39;uploaded&amp;#39; ][ &amp;#39;name&amp;#39; ] );   // Can we move the file to the upload folder?  // 完全没做过滤.  // 上传一个PHP文件也是可以的.  if( !move_uploaded_file( $_FILES[ &amp;#39;uploaded&amp;#39; ][ &amp;#39;tmp_name&amp;#39; ], $target_path ) ) {  // No  echo &amp;#39;&amp;lt;pre&amp;gt;Your image was not uploaded.">
</head><body class=article-page>
<script>(function(){const e="StackColorScheme";localStorage.getItem(e)||localStorage.setItem(e,"auto")})()</script><script>(function(){const t="StackColorScheme",e=localStorage.getItem(t),n=window.matchMedia("(prefers-color-scheme: dark)").matches===!0;e=="dark"||e==="auto"&&n?document.documentElement.dataset.scheme="dark":document.documentElement.dataset.scheme="light"})()</script>
<div class="container main-container flex on-phone--column compact"><aside class="sidebar left-sidebar sticky">
<button class="hamburger hamburger--spin" type=button id=toggle-menu aria-label="Toggle Menu">
<span class=hamburger-box>
<span class=hamburger-inner></span>
</span>
</button>
<header>
<figure class=site-avatar>
<a href=/>
<img src=/img/avatar_hu8e30117ca872857dd9f41f234a693048_441529_300x0_resize_box_3.png width=300 height=300 class=site-logo loading=lazy alt=Avatar>
</a>
</figure><div class=site-meta>
<h1 class=site-name><a href=/>SDTTTTT</a></h1><h2 class=site-description>臭鱼烂虾</h2></div></header><ol class=menu id=main-menu>
<div class=menu-bottom-section>
<li id=dark-mode-toggle><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-left" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="8" cy="12" r="2"/><rect x="2" y="6" width="20" height="12" rx="6"/></svg><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-toggle-right" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="16" cy="12" r="2"/><rect x="2" y="6" width="20" height="12" rx="6"/></svg>
<span>Dark Mode</span>
</li></div></ol></aside><main class="main full-width">
<article class=main-article>
<header class=article-header>
<div class=article-details>
<div class=article-title-wrapper>
<h2 class=article-title>
<a href=/blog/file_upload/>File Upload</a>
</h2></div><footer class=article-time>
<div><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-calendar-time" width="56" height="56" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><path d="M11.795 21H5a2 2 0 01-2-2V7a2 2 0 012-2h12a2 2 0 012 2v4"/><circle cx="18" cy="18" r="4"/><path d="M15 3v4"/><path d="M7 3v4"/><path d="M3 11h16"/><path d="M18 16.496V18l1 1"/></svg>
<time class=article-time--published>Apr 12, 2020</time>
</div><div><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 15"/></svg>
<time class=article-time--reading>
5 minute read
</time>
</div></footer></div></header><section class=article-content>
<p>DVWA File upload 过关秘籍.</p><h3 id=low>LOW</h3><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-PHP data-lang=PHP><span style=display:flex><span><span style=color:#66d9ef>if</span>( <span style=color:#a6e22e>isset</span>( $_POST[ <span style=color:#e6db74>&#39;Upload&#39;</span> ] ) ) {
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Where are we going to be writing to?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $target_path  <span style=color:#f92672>=</span> <span style=color:#a6e22e>DVWA_WEB_PAGE_TO_ROOT</span> <span style=color:#f92672>.</span> <span style=color:#e6db74>&#34;hackable/uploads/&#34;</span>;
</span></span><span style=display:flex><span>    $target_path <span style=color:#f92672>.=</span> <span style=color:#a6e22e>basename</span>( $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;name&#39;</span> ] );
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Can we move the file to the upload folder?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// 完全没做过滤.
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// 上传一个PHP文件也是可以的.
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#66d9ef>if</span>( <span style=color:#f92672>!</span><span style=color:#a6e22e>move_uploaded_file</span>( $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;tmp_name&#39;</span> ], $target_path ) ) {
</span></span><span style=display:flex><span>        <span style=color:#75715e>// No
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>    <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Yes!
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#34;&lt;pre&gt;</span><span style=color:#e6db74>{</span>$target_path<span style=color:#e6db74>}</span><span style=color:#e6db74> succesfully uploaded!&lt;/pre&gt;&#34;</span>;
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><h3 id=medium>Medium</h3><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-PHP data-lang=PHP><span style=display:flex><span><span style=color:#66d9ef>if</span>( <span style=color:#a6e22e>isset</span>( $_POST[ <span style=color:#e6db74>&#39;Upload&#39;</span> ] ) ) {
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Where are we going to be writing to?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $target_path  <span style=color:#f92672>=</span> <span style=color:#a6e22e>DVWA_WEB_PAGE_TO_ROOT</span> <span style=color:#f92672>.</span> <span style=color:#e6db74>&#34;hackable/uploads/&#34;</span>;
</span></span><span style=display:flex><span>    $target_path <span style=color:#f92672>.=</span> <span style=color:#a6e22e>basename</span>( $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;name&#39;</span> ] );
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// File information
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $uploaded_name <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;name&#39;</span> ];
</span></span><span style=display:flex><span>    $uploaded_type <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;type&#39;</span> ];
</span></span><span style=display:flex><span>    $uploaded_size <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;size&#39;</span> ];
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Is it an image?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// // 开始做了一些过滤
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// 下面是官方对$_FILES 函数的描述
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>//  [name] =&gt; MyFile.txt (comes from the browser, so treat as tainted)
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>//         [type] =&gt; text/plain  (not sure where it gets this from - assume the browser, so treat as tainted)
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>//         [tmp_name] =&gt; /tmp/php/php1h4j1o (could be anywhere on your system, depending on your config        settings, but the user has no control, so this isn&#39;t tainted)
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>//         [error] =&gt; UPLOAD_ERR_OK  (= 0)
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>//         [size] =&gt; 123   (the size in bytes)
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    
</span></span><span style=display:flex><span>    <span style=color:#75715e>// 其中对name和type的description的描述都是 `treat as tainted`(被污染的)
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// 这意味着它有可能会被修改 unsafe
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    
</span></span><span style=display:flex><span>    <span style=color:#75715e>// 我们可以尝试上传一个PHP文件，使用一些拦截请求工具，修改即将发出的请求.
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// 来达到修改`name`中的后缀名和`type`中的媒体类型.
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#66d9ef>if</span>( ( $uploaded_type <span style=color:#f92672>==</span> <span style=color:#e6db74>&#34;image/jpeg&#34;</span> <span style=color:#f92672>||</span> $uploaded_type <span style=color:#f92672>==</span> <span style=color:#e6db74>&#34;image/png&#34;</span> ) <span style=color:#f92672>&amp;&amp;</span>
</span></span><span style=display:flex><span>        ( $uploaded_size <span style=color:#f92672>&lt;</span> <span style=color:#ae81ff>100000</span> ) ) {
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Can we move the file to the upload folder?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>if</span>( <span style=color:#f92672>!</span><span style=color:#a6e22e>move_uploaded_file</span>( $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;tmp_name&#39;</span> ], $target_path ) ) {
</span></span><span style=display:flex><span>            <span style=color:#75715e>// No
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>            <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>        <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>            <span style=color:#75715e>// Yes!
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>            <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#34;&lt;pre&gt;</span><span style=color:#e6db74>{</span>$target_path<span style=color:#e6db74>}</span><span style=color:#e6db74> succesfully uploaded!&lt;/pre&gt;&#34;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>    <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Invalid file
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded. We can only accept JPEG or PNG images.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><h3 id=high>High</h3><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-PHP data-lang=PHP><span style=display:flex><span><span style=color:#66d9ef>if</span>( <span style=color:#a6e22e>isset</span>( $_POST[ <span style=color:#e6db74>&#39;Upload&#39;</span> ] ) ) {
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Where are we going to be writing to?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $target_path  <span style=color:#f92672>=</span> <span style=color:#a6e22e>DVWA_WEB_PAGE_TO_ROOT</span> <span style=color:#f92672>.</span> <span style=color:#e6db74>&#34;hackable/uploads/&#34;</span>;
</span></span><span style=display:flex><span>    $target_path <span style=color:#f92672>.=</span> <span style=color:#a6e22e>basename</span>( $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;name&#39;</span> ] );
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// File information
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $uploaded_name <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;name&#39;</span> ];
</span></span><span style=display:flex><span>        <span style=color:#75715e>// jpg
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $uploaded_ext  <span style=color:#f92672>=</span> <span style=color:#a6e22e>substr</span>( $uploaded_name, <span style=color:#a6e22e>strrpos</span>( $uploaded_name, <span style=color:#e6db74>&#39;.&#39;</span> ) <span style=color:#f92672>+</span> <span style=color:#ae81ff>1</span>);
</span></span><span style=display:flex><span>    
</span></span><span style=display:flex><span>    <span style=color:#75715e>// file size
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $uploaded_size <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;size&#39;</span> ];
</span></span><span style=display:flex><span>    
</span></span><span style=display:flex><span>    <span style=color:#75715e>// tmp_name 是临时副本的名字
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $uploaded_tmp  <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;tmp_name&#39;</span> ];
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Is it an image?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// 和上面的比起来多个一个文件后缀名的判断.
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// strtolower 转小写
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// 扩展名只要满足jpeg,png或者jpg就行
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#66d9ef>if</span>( ( <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#34;jpg&#34;</span> <span style=color:#f92672>||</span> <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#34;jpeg&#34;</span> <span style=color:#f92672>||</span> <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#34;png&#34;</span> ) <span style=color:#f92672>&amp;&amp;</span>
</span></span><span style=display:flex><span>        ( $uploaded_size <span style=color:#f92672>&lt;</span> <span style=color:#ae81ff>100000</span> ) <span style=color:#f92672>&amp;&amp;</span>
</span></span><span style=display:flex><span>        <span style=color:#75715e>// getimagesize 获取图像信息
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#75715e>// 这个函数保证你穿的一定得是个图像
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#75715e>// 可以用图片木马绕过
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#a6e22e>getimagesize</span>( $uploaded_tmp ) ) {
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Can we move the file to the upload folder?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>if</span>( <span style=color:#f92672>!</span><span style=color:#a6e22e>move_uploaded_file</span>( $uploaded_tmp, $target_path ) ) {
</span></span><span style=display:flex><span>            <span style=color:#75715e>// No
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>            <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>        <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>            <span style=color:#75715e>// Yes!
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>            <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#34;&lt;pre&gt;</span><span style=color:#e6db74>{</span>$target_path<span style=color:#e6db74>}</span><span style=color:#e6db74> succesfully uploaded!&lt;/pre&gt;&#34;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>    <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Invalid file
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded. We can only accept JPEG or PNG images.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><h3 id=high-1>High</h3><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-PHP data-lang=PHP><span style=display:flex><span><span style=color:#66d9ef>if</span>( <span style=color:#a6e22e>isset</span>( $_POST[ <span style=color:#e6db74>&#39;Upload&#39;</span> ] ) ) {
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Where are we going to be writing to?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $target_path  <span style=color:#f92672>=</span> <span style=color:#a6e22e>DVWA_WEB_PAGE_TO_ROOT</span> <span style=color:#f92672>.</span> <span style=color:#e6db74>&#34;hackable/uploads/&#34;</span>;
</span></span><span style=display:flex><span>    $target_path <span style=color:#f92672>.=</span> <span style=color:#a6e22e>basename</span>( $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;name&#39;</span> ] );
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// File information
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $uploaded_name <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;name&#39;</span> ];
</span></span><span style=display:flex><span>    $uploaded_ext  <span style=color:#f92672>=</span> <span style=color:#a6e22e>substr</span>( $uploaded_name, <span style=color:#a6e22e>strrpos</span>( $uploaded_name, <span style=color:#e6db74>&#39;.&#39;</span> ) <span style=color:#f92672>+</span> <span style=color:#ae81ff>1</span>);
</span></span><span style=display:flex><span>    $uploaded_size <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;size&#39;</span> ];
</span></span><span style=display:flex><span>    $uploaded_tmp  <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;tmp_name&#39;</span> ];
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Is it an image?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#75715e>// 对比上面多验证了文件的后缀名
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#66d9ef>if</span>( ( <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#34;jpg&#34;</span> <span style=color:#f92672>||</span> <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#34;jpeg&#34;</span> <span style=color:#f92672>||</span> <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#34;png&#34;</span> ) <span style=color:#f92672>&amp;&amp;</span>
</span></span><span style=display:flex><span>        ( $uploaded_size <span style=color:#f92672>&lt;</span> <span style=color:#ae81ff>100000</span> ) <span style=color:#f92672>&amp;&amp;</span>
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>        
</span></span><span style=display:flex><span>       
</span></span><span style=display:flex><span>        <span style=color:#75715e>// 函数会通过读取文件头，返回图片的长、宽等信息，如果没有相关的图片文件头，函数会报错
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#a6e22e>getimagesize</span>( $uploaded_tmp ) ) {
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>        <span style=color:#75715e>// 可以看到，High级别的代码读取文件名中最后一个”.”后的字符串，期望通过文件名来限制文件类型
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#75715e>// 因此要求上传文件名形式必须是”*.jpg”、”*.jpeg” 、”*.png”之一
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#75715e>// 同时，getimagesize函数更是限制了上传文件的文件头必须为图像类型
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Can we move the file to the upload folder?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>if</span>( <span style=color:#f92672>!</span><span style=color:#a6e22e>move_uploaded_file</span>( $uploaded_tmp, $target_path ) ) {
</span></span><span style=display:flex><span>            <span style=color:#75715e>// No
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>            <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>        <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>            <span style=color:#75715e>// Yes!
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>            <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#34;&lt;pre&gt;</span><span style=color:#e6db74>{</span>$target_path<span style=color:#e6db74>}</span><span style=color:#e6db74> succesfully uploaded!&lt;/pre&gt;&#34;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>    <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Invalid file
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded. We can only accept JPEG or PNG images.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><h3 id=impossible>Impossible</h3><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-PHP data-lang=PHP><span style=display:flex><span><span style=color:#66d9ef>if</span>( <span style=color:#a6e22e>isset</span>( $_POST[ <span style=color:#e6db74>&#39;Upload&#39;</span> ] ) ) {
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Check Anti-CSRF token
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#a6e22e>checkToken</span>( $_REQUEST[ <span style=color:#e6db74>&#39;user_token&#39;</span> ], $_SESSION[ <span style=color:#e6db74>&#39;session_token&#39;</span> ], <span style=color:#e6db74>&#39;index.php&#39;</span> );
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// File information
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $uploaded_name <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;name&#39;</span> ];
</span></span><span style=display:flex><span>    $uploaded_ext  <span style=color:#f92672>=</span> <span style=color:#a6e22e>substr</span>( $uploaded_name, <span style=color:#a6e22e>strrpos</span>( $uploaded_name, <span style=color:#e6db74>&#39;.&#39;</span> ) <span style=color:#f92672>+</span> <span style=color:#ae81ff>1</span>);
</span></span><span style=display:flex><span>    $uploaded_size <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;size&#39;</span> ];
</span></span><span style=display:flex><span>    $uploaded_type <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;type&#39;</span> ];
</span></span><span style=display:flex><span>    $uploaded_tmp  <span style=color:#f92672>=</span> $_FILES[ <span style=color:#e6db74>&#39;uploaded&#39;</span> ][ <span style=color:#e6db74>&#39;tmp_name&#39;</span> ];
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Where are we going to be writing to?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $target_path   <span style=color:#f92672>=</span> <span style=color:#a6e22e>DVWA_WEB_PAGE_TO_ROOT</span> <span style=color:#f92672>.</span> <span style=color:#e6db74>&#39;hackable/uploads/&#39;</span>;
</span></span><span style=display:flex><span>    <span style=color:#75715e>//$target_file   = basename( $uploaded_name, &#39;.&#39; . $uploaded_ext ) . &#39;-&#39;;
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// MD5 加密
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $target_file   <span style=color:#f92672>=</span>  <span style=color:#a6e22e>md5</span>( <span style=color:#a6e22e>uniqid</span>() <span style=color:#f92672>.</span> $uploaded_name ) <span style=color:#f92672>.</span> <span style=color:#e6db74>&#39;.&#39;</span> <span style=color:#f92672>.</span> $uploaded_ext;
</span></span><span style=display:flex><span>    $temp_file     <span style=color:#f92672>=</span> ( ( <span style=color:#a6e22e>ini_get</span>( <span style=color:#e6db74>&#39;upload_tmp_dir&#39;</span> ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#39;&#39;</span> ) <span style=color:#f92672>?</span> ( <span style=color:#a6e22e>sys_get_temp_dir</span>() ) <span style=color:#f92672>:</span> ( <span style=color:#a6e22e>ini_get</span>( <span style=color:#e6db74>&#39;upload_tmp_dir&#39;</span> ) ) );
</span></span><span style=display:flex><span>    $temp_file    <span style=color:#f92672>.=</span> <span style=color:#a6e22e>DIRECTORY_SEPARATOR</span> <span style=color:#f92672>.</span> <span style=color:#a6e22e>md5</span>( <span style=color:#a6e22e>uniqid</span>() <span style=color:#f92672>.</span> $uploaded_name ) <span style=color:#f92672>.</span> <span style=color:#e6db74>&#39;.&#39;</span> <span style=color:#f92672>.</span> $uploaded_ext;
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>    <span style=color:#75715e>// Is it an image?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    <span style=color:#66d9ef>if</span>( ( <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#39;jpg&#39;</span> <span style=color:#f92672>||</span> <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#39;jpeg&#39;</span> <span style=color:#f92672>||</span> <span style=color:#a6e22e>strtolower</span>( $uploaded_ext ) <span style=color:#f92672>==</span> <span style=color:#e6db74>&#39;png&#39;</span> ) <span style=color:#f92672>&amp;&amp;</span>
</span></span><span style=display:flex><span>        ( $uploaded_size <span style=color:#f92672>&lt;</span> <span style=color:#ae81ff>100000</span> ) <span style=color:#f92672>&amp;&amp;</span>
</span></span><span style=display:flex><span>        ( $uploaded_type <span style=color:#f92672>==</span> <span style=color:#e6db74>&#39;image/jpeg&#39;</span> <span style=color:#f92672>||</span> $uploaded_type <span style=color:#f92672>==</span> <span style=color:#e6db74>&#39;image/png&#39;</span> ) <span style=color:#f92672>&amp;&amp;</span>
</span></span><span style=display:flex><span>        <span style=color:#a6e22e>getimagesize</span>( $uploaded_tmp ) ) {
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Strip any metadata, by re-encoding image (Note, using php-Imagick is recommended over php-GD)
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>if</span>( $uploaded_type <span style=color:#f92672>==</span> <span style=color:#e6db74>&#39;image/jpeg&#39;</span> ) {
</span></span><span style=display:flex><span>            $img <span style=color:#f92672>=</span> <span style=color:#a6e22e>imagecreatefromjpeg</span>( $uploaded_tmp );
</span></span><span style=display:flex><span>            <span style=color:#a6e22e>imagejpeg</span>( $img, $temp_file, <span style=color:#ae81ff>100</span>);
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>        <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>            $img <span style=color:#f92672>=</span> <span style=color:#a6e22e>imagecreatefrompng</span>( $uploaded_tmp );
</span></span><span style=display:flex><span>            <span style=color:#a6e22e>imagepng</span>( $img, $temp_file, <span style=color:#ae81ff>9</span>);
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>        <span style=color:#a6e22e>imagedestroy</span>( $img );
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Can we move the file to the web root from the temp folder?
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>if</span>( <span style=color:#a6e22e>rename</span>( $temp_file, ( <span style=color:#a6e22e>getcwd</span>() <span style=color:#f92672>.</span> <span style=color:#a6e22e>DIRECTORY_SEPARATOR</span> <span style=color:#f92672>.</span> $target_path <span style=color:#f92672>.</span> $target_file ) ) ) {
</span></span><span style=display:flex><span>            <span style=color:#75715e>// Yes!
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>            <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#34;&lt;pre&gt;&lt;a href=&#39;</span><span style=color:#e6db74>${</span>target_path}${target_file}&#39;&gt;${target_file<span style=color:#e6db74>}</span><span style=color:#e6db74>&lt;/a&gt; succesfully uploaded!&lt;/pre&gt;&#34;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>        <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>            <span style=color:#75715e>// No
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>            <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Delete any temp files
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>if</span>( <span style=color:#a6e22e>file_exists</span>( $temp_file ) )
</span></span><span style=display:flex><span>            <span style=color:#a6e22e>unlink</span>( $temp_file );
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>    <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>        <span style=color:#75715e>// Invalid file
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#66d9ef>echo</span> <span style=color:#e6db74>&#39;&lt;pre&gt;Your image was not uploaded. We can only accept JPEG or PNG images.&lt;/pre&gt;&#39;</span>;
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>}
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span><span style=color:#75715e>// Generate Anti-CSRF token
</span></span></span><span style=display:flex><span><span style=color:#75715e></span><span style=color:#a6e22e>generateSessionToken</span>();
</span></span></code></pre></div><h3 id=extension>Extension</h3><p><strong>00%截断</strong></p><div class=highlight><pre tabindex=0 style=color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4><code class=language-PHP data-lang=PHP><span style=display:flex><span>$is_upload <span style=color:#f92672>=</span> <span style=color:#66d9ef>false</span>;
</span></span><span style=display:flex><span>$msg <span style=color:#f92672>=</span> <span style=color:#66d9ef>null</span>;
</span></span><span style=display:flex><span><span style=color:#66d9ef>if</span>(<span style=color:#a6e22e>isset</span>($_POST[<span style=color:#e6db74>&#39;submit&#39;</span>])){
</span></span><span style=display:flex><span>    <span style=color:#75715e>// 白名单
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>    $ext_arr <span style=color:#f92672>=</span> <span style=color:#66d9ef>array</span>(<span style=color:#e6db74>&#39;jpg&#39;</span>,<span style=color:#e6db74>&#39;png&#39;</span>,<span style=color:#e6db74>&#39;gif&#39;</span>);
</span></span><span style=display:flex><span>    $file_ext <span style=color:#f92672>=</span> <span style=color:#a6e22e>substr</span>($_FILES[<span style=color:#e6db74>&#39;upload_file&#39;</span>][<span style=color:#e6db74>&#39;name&#39;</span>],<span style=color:#a6e22e>strrpos</span>($_FILES[<span style=color:#e6db74>&#39;upload_file&#39;</span>][<span style=color:#e6db74>&#39;name&#39;</span>],<span style=color:#e6db74>&#34;.&#34;</span>)<span style=color:#f92672>+</span><span style=color:#ae81ff>1</span>);
</span></span><span style=display:flex><span>    <span style=color:#66d9ef>if</span>(<span style=color:#a6e22e>in_array</span>($file_ext,$ext_arr)){
</span></span><span style=display:flex><span>        $temp_file <span style=color:#f92672>=</span> $_FILES[<span style=color:#e6db74>&#39;upload_file&#39;</span>][<span style=color:#e6db74>&#39;tmp_name&#39;</span>];
</span></span><span style=display:flex><span>        <span style=color:#75715e>// 注意这个位置
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        <span style=color:#75715e>// 最后拼接的储存路径，是由用户提交上的数据来做为路径
</span></span></span><span style=display:flex><span><span style=color:#75715e></span>        $img_path <span style=color:#f92672>=</span> $_POST[<span style=color:#e6db74>&#39;save_path&#39;</span>]<span style=color:#f92672>.</span><span style=color:#e6db74>&#34;/&#34;</span><span style=color:#f92672>.</span><span style=color:#a6e22e>rand</span>(<span style=color:#ae81ff>10</span>, <span style=color:#ae81ff>99</span>)<span style=color:#f92672>.</span><span style=color:#a6e22e>date</span>(<span style=color:#e6db74>&#34;YmdHis&#34;</span>)<span style=color:#f92672>.</span><span style=color:#e6db74>&#34;.&#34;</span><span style=color:#f92672>.</span>$file_ext;
</span></span><span style=display:flex><span>
</span></span><span style=display:flex><span>        <span style=color:#66d9ef>if</span>(<span style=color:#a6e22e>move_uploaded_file</span>($temp_file,$img_path)){
</span></span><span style=display:flex><span>            $is_upload <span style=color:#f92672>=</span> <span style=color:#66d9ef>true</span>;
</span></span><span style=display:flex><span>        } <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>            $msg <span style=color:#f92672>=</span> <span style=color:#e6db74>&#34;上传失败&#34;</span>;
</span></span><span style=display:flex><span>        }
</span></span><span style=display:flex><span>    } <span style=color:#66d9ef>else</span> {
</span></span><span style=display:flex><span>        $msg <span style=color:#f92672>=</span> <span style=color:#e6db74>&#34;只允许上传.jpg|.png|.gif类型文件！&#34;</span>;
</span></span><span style=display:flex><span>    }
</span></span><span style=display:flex><span>}
</span></span></code></pre></div><p>代码采用的白名单校验，只允许上传图片格式，理论上这个上传是不好绕过的。</p><p>但是后面采用保存文件的时候，是路径拼接的形式，而路径又是从前端获取，所以我们可以在路径上做手脚。</p><p>如下上传，显示文件路径中有个空格，这并不是真正意义上的空格，而是%00截断后显示成的空格。</p><blockquote>
<p>在url中%00表示ascll码中的0 ，而ascii中0作为特殊字符保留，表示字符串结束，所以当url中出现%00时就会认为读取已结束 (php版本要小于5.3.4，5.3.4及以上已经修复该问题)</p></blockquote></section><footer class=article-footer>
<section class=article-tags>
<a href=/tags/penetration-test/>penetration test</a>
</section><section class=article-lastmod><svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-clock" width="24" height="24" viewBox="0 0 24 24" stroke-width="2" stroke="currentcolor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z"/><circle cx="12" cy="12" r="9"/><polyline points="12 7 12 12 15 15"/></svg>
<span>
Last updated on Sep 24, 2020 18:06 CST
</span>
</section></footer></article><aside class=related-contents--wrapper>
<h2 class=section-title>Related contents</h2><div class=related-contents>
<div class="flex article-list--tile">
<article>
<a href=/blog/sql_injection_blind/>
<div class=article-details>
<h2 class=article-title>Sql Injection Blind</h2></div></a>
</article><article>
<a href=/blog/sql_injection/>
<div class=article-details>
<h2 class=article-title>SQL Injection</h2></div></a>
</article></div></div></aside><div id=gitalk-container></div><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/gitalk@1.7.2/dist/gitalk.css>
<script src=https://cdn.jsdelivr.net/npm/gitalk@1.7.2/dist/gitalk.min.js></script>
<script src=https://cdn.jsdelivr.net/npm/blueimp-md5@2.18.0/js/md5.min.js></script>
<script>const gitalk=new Gitalk({clientID:"97eb9ce8ac126f0c7833",clientSecret:"5da440441b500b0b016928640712a1b1a03a5f8f",repo:"sdttttt/sdttttt.github.io",owner:"sdttttt",admin:["sdttttt"],distractionFreeMode:!1,id:md5(location.pathname)});(function(){if(["localhost","127.0.0.1"].indexOf(window.location.hostname)!=-1){document.getElementById("gitalk-container").innerHTML="Gitalk comments not available by default when the website is previewed locally.";return}gitalk.render("gitalk-container")})()</script>
<footer class=site-footer>
<section class=copyright>
&copy;
2022 SDTTTTT
</section><section class=powerby>
Built with <a href=https://gohugo.io/ target=_blank rel=noopener>Hugo</a> <br>
Theme <b><a href=https://github.com/CaiJimmy/hugo-theme-stack target=_blank rel=noopener data-version=3.10.0>Stack</a></b> designed by <a href=https://jimmycai.com target=_blank rel=noopener>Jimmy</a>
</section></footer><div class=pswp tabindex=-1 role=dialog aria-hidden=true>
<div class=pswp__bg></div><div class=pswp__scroll-wrap>
<div class=pswp__container>
<div class=pswp__item></div><div class=pswp__item></div><div class=pswp__item></div></div><div class="pswp__ui pswp__ui--hidden">
<div class=pswp__top-bar>
<div class=pswp__counter></div><button class="pswp__button pswp__button--close" title="Close (Esc)"></button>
<button class="pswp__button pswp__button--share" title=Share></button>
<button class="pswp__button pswp__button--fs" title="Toggle fullscreen"></button>
<button class="pswp__button pswp__button--zoom" title="Zoom in/out"></button>
<div class=pswp__preloader>
<div class=pswp__preloader__icn>
<div class=pswp__preloader__cut>
<div class=pswp__preloader__donut></div></div></div></div></div><div class="pswp__share-modal pswp__share-modal--hidden pswp__single-tap">
<div class=pswp__share-tooltip></div></div><button class="pswp__button pswp__button--arrow--left" title="Previous (arrow left)">
</button>
<button class="pswp__button pswp__button--arrow--right" title="Next (arrow right)">
</button>
<div class=pswp__caption>
<div class=pswp__caption__center></div></div></div></div></div><script src=https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.min.js integrity="sha256-ePwmChbbvXbsO02lbM3HoHbSHTHFAeChekF1xKJdleo=" crossorigin=anonymous defer></script><script src=https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe-ui-default.min.js integrity="sha256-UKkzOn/w1mBxRmLLGrSeyB4e1xbrp4xylgAWb3M42pU=" crossorigin=anonymous defer></script><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/default-skin/default-skin.css integrity="sha256-c0uckgykQ9v5k+IqViZOZKc47Jn7KQil4/MP3ySA3F8=" crossorigin=anonymous><link rel=stylesheet href=https://cdn.jsdelivr.net/npm/photoswipe@4.1.3/dist/photoswipe.css integrity="sha256-SBLU4vv6CA6lHsZ1XyTdhyjJxCjPif/TRkjnsyGAGnE=" crossorigin=anonymous>
</main></div><script src=https://cdn.jsdelivr.net/npm/node-vibrant@3.1.5/dist/vibrant.min.js integrity="sha256-5NovOZc4iwiAWTYIFiIM7DxKUXKWvpVEuMEPLzcm5/g=" crossorigin=anonymous></script><script type=text/javascript src=/ts/main.js defer></script>
<script>(function(){const e=document.createElement("link");e.href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&display=swap",e.type="text/css",e.rel="stylesheet",document.head.appendChild(e)})()</script>
</body></html>